//+------------------------------------------------------------------+
//|                                                 TradingModule.mqh |
//|                                      交易模块 - 负责交易操作管理   |
//|                                                                  |
//+------------------------------------------------------------------+
#property strict

// 包含下单模块
#include "OrderModule.mqh"

//+------------------------------------------------------------------+
//| 交易模块类                                                        |
//+------------------------------------------------------------------+
class CTradingModule
{
private:
   COrderModule      *m_orderModule;    // 下单模块
   int               m_magicNumber;     // 魔术号
   string            m_symbol;          // 交易品种
   double            m_riskPercent;     // 风险百分比
   
public:
   // 构造函数
   CTradingModule(int magicNumber, string symbol, double riskPercent);
   
   // 析构函数
   ~CTradingModule();
   
   // 初始化
   bool              Initialize();
   
   // 执行买单
   int               ExecuteBuyOrder(double lotSize, double stopLoss, double takeProfit = 0, string comment = "");
   
   // 执行卖单
   int               ExecuteSellOrder(double lotSize, double stopLoss, double takeProfit = 0, string comment = "");
   
   // 按类型关闭订单
   int               CloseOrdersByType(int orderType);
   
   // 关闭所有订单
   int               CloseAllOrders();
   
   // 删除挂单
   int               DeletePendingOrders();
   
   // 计算手数
   double            CalculateLotSize(double entryPrice, double stopLoss, double riskPercent);
   
   // 获取订单统计
   int               GetOrderCount(int orderType = -1);
   
   // 获取总盈亏
   double            GetTotalProfit();
   
   // 移动止损到盈亏平衡点
   bool              MoveToBreakeven(double minProfitPoints = 10.0);
   
   // 执行手动买单（从GUI获取参数）
   int               ExecuteManualBuyOrder(CGUIModule* guiModule, CPriceModule* priceModule);
   
   // 执行手动卖单（从GUI获取参数）
   int               ExecuteManualSellOrder(CGUIModule* guiModule, CPriceModule* priceModule);
   
   // 更新手数计算并显示
   void              UpdateLotSizeCalculation(CGUIModule* guiModule, CPriceModule* priceModule);
   
private:
   // 验证交易参数
   bool              ValidateTradeParams(double lotSize, double stopLoss);
   
   // 标准化手数
   double            NormalizeLotSize(double lotSize);
   
   // 标准化价格
   double            NormalizePrice(double price);
};

//+------------------------------------------------------------------+
//| 构造函数                                                          |
//+------------------------------------------------------------------+
CTradingModule::CTradingModule(int magicNumber, string symbol, double riskPercent)
{
   m_magicNumber = magicNumber;
   m_symbol = (symbol == "") ? Symbol() : symbol;
   m_riskPercent = riskPercent;
   m_orderModule = NULL;
}

//+------------------------------------------------------------------+
//| 析构函数                                                          |
//+------------------------------------------------------------------+
CTradingModule::~CTradingModule()
{
   if(m_orderModule != NULL)
   {
      delete m_orderModule;
      m_orderModule = NULL;
   }
}

//+------------------------------------------------------------------+
//| 初始化                                                            |
//+------------------------------------------------------------------+
bool CTradingModule::Initialize()
{
   m_orderModule = new COrderModule(m_magicNumber, m_symbol, 3.0);
   
   if(m_orderModule == NULL)
   {
      Print("错误: 交易模块初始化失败");
      return false;
   }
   
   Print("交易模块初始化成功 - 品种: ", m_symbol, ", 魔术号: ", m_magicNumber);
   return true;
}

//+------------------------------------------------------------------+
//| 执行买单                                                          |
//+------------------------------------------------------------------+
int CTradingModule::ExecuteBuyOrder(double lotSize, double stopLoss, double takeProfit = 0, string comment = "")
{
   if(m_orderModule == NULL) return -1;
   
   lotSize = NormalizeLotSize(lotSize);
   stopLoss = NormalizePrice(stopLoss);
   takeProfit = NormalizePrice(takeProfit);
   
   if(!ValidateTradeParams(lotSize, stopLoss))
   {
      Print("买单参数验证失败");
      return -1;
   }
   
   int ticket = m_orderModule.BuyMarket(lotSize, stopLoss, takeProfit, comment);
   
   if(ticket > 0)
   {
      Print("买单执行成功 - 订单号: ", ticket, ", 手数: ", lotSize, ", 止损: ", stopLoss);
   }
   else
   {
      Print("买单执行失败 - 错误: ", GetLastError());
   }
   
   return ticket;
}

//+------------------------------------------------------------------+
//| 执行卖单                                                          |
//+------------------------------------------------------------------+
int CTradingModule::ExecuteSellOrder(double lotSize, double stopLoss, double takeProfit = 0, string comment = "")
{
   if(m_orderModule == NULL) return -1;
   
   lotSize = NormalizeLotSize(lotSize);
   stopLoss = NormalizePrice(stopLoss);
   takeProfit = NormalizePrice(takeProfit);
   
   if(!ValidateTradeParams(lotSize, stopLoss))
   {
      Print("卖单参数验证失败");
      return -1;
   }
   
   int ticket = m_orderModule.SellMarket(lotSize, stopLoss, takeProfit, comment);
   
   if(ticket > 0)
   {
      Print("卖单执行成功 - 订单号: ", ticket, ", 手数: ", lotSize, ", 止损: ", stopLoss);
   }
   else
   {
      Print("卖单执行失败 - 错误: ", GetLastError());
   }
   
   return ticket;
}

//+------------------------------------------------------------------+
//| 按类型关闭订单                                                    |
//+------------------------------------------------------------------+
int CTradingModule::CloseOrdersByType(int orderType)
{
   int total = OrdersTotal();
   int closed = 0;
   
   for(int i = total - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber && OrderType() == orderType)
         {
            bool result = false;
            if(orderType == OP_BUY)
            {
               result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(m_symbol, MODE_BID), 3);
            }
            else if(orderType == OP_SELL)
            {
               result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(m_symbol, MODE_ASK), 3);
            }
            
            if(result) 
            {
               closed++;
               Print("关闭订单成功 - 订单号: ", OrderTicket());
            }
            else
            {
               Print("关闭订单失败 - 订单号: ", OrderTicket(), ", 错误: ", GetLastError());
            }
         }
      }
   }
   
   Print("关闭", (orderType == OP_BUY ? "买单" : "卖单"), " ", closed, " 个");
   return closed;
}

//+------------------------------------------------------------------+
//| 关闭所有订单                                                      |
//+------------------------------------------------------------------+
int CTradingModule::CloseAllOrders()
{
   int totalClosed = 0;
   totalClosed += CloseOrdersByType(OP_BUY);
   totalClosed += CloseOrdersByType(OP_SELL);
   totalClosed += DeletePendingOrders();
   
   Print("总共关闭订单: ", totalClosed, " 个");
   return totalClosed;
}

//+------------------------------------------------------------------+
//| 删除挂单                                                          |
//+------------------------------------------------------------------+
int CTradingModule::DeletePendingOrders()
{
   int total = OrdersTotal();
   int deleted = 0;
   
   for(int i = total - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            if(OrderType() > OP_SELL) // 挂单类型
            {
               if(OrderDelete(OrderTicket()))
               {
                  deleted++;
                  Print("删除挂单成功 - 订单号: ", OrderTicket());
               }
               else
               {
                  Print("删除挂单失败 - 订单号: ", OrderTicket(), ", 错误: ", GetLastError());
               }
            }
         }
      }
   }
   
   Print("删除挂单 ", deleted, " 个");
   return deleted;
}

//+------------------------------------------------------------------+
//| 计算手数                                                          |
//+------------------------------------------------------------------+
double CTradingModule::CalculateLotSize(double entryPrice, double stopLoss, double riskPercent)
{
   if(entryPrice <= 0 || stopLoss <= 0 || riskPercent <= 0)
      return 0.01;
   
   double riskAmount = AccountBalance() * riskPercent / 100.0;
   double stopLossPoints = MathAbs(entryPrice - stopLoss) / Point;
   double lotSize = 0.01;
   
   if(stopLossPoints > 0)
   {
      double tickValue = MarketInfo(m_symbol, MODE_TICKVALUE);
      if(tickValue > 0)
      {
         lotSize = riskAmount / (stopLossPoints * tickValue);
         lotSize = NormalizeLotSize(lotSize);
      }
   }
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| 获取订单数量                                                      |
//+------------------------------------------------------------------+
int CTradingModule::GetOrderCount(int orderType = -1)
{
   int total = OrdersTotal();
   int count = 0;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            if(orderType == -1 || OrderType() == orderType)
            {
               count++;
            }
         }
      }
   }
   
   return count;
}

//+------------------------------------------------------------------+
//| 获取总盈亏                                                        |
//+------------------------------------------------------------------+
double CTradingModule::GetTotalProfit()
{
   int total = OrdersTotal();
   double totalProfit = 0;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            totalProfit += OrderProfit() + OrderSwap() + OrderCommission();
         }
      }
   }
   
   return totalProfit;
}

//+------------------------------------------------------------------+
//| 移动止损到盈亏平衡点                                              |
//+------------------------------------------------------------------+
bool CTradingModule::MoveToBreakeven(double minProfitPoints = 10.0)
{
   int total = OrdersTotal();
   int modified = 0;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
            {
               double currentPrice = (OrderType() == OP_BUY) ? MarketInfo(m_symbol, MODE_BID) : MarketInfo(m_symbol, MODE_ASK);
               double profitPoints = 0;
               
               if(OrderType() == OP_BUY)
               {
                  profitPoints = (currentPrice - OrderOpenPrice()) / Point;
               }
               else
               {
                  profitPoints = (OrderOpenPrice() - currentPrice) / Point;
               }
               
               if(profitPoints >= minProfitPoints)
               {
                  double newStopLoss = NormalizePrice(OrderOpenPrice());
                  
                  if(MathAbs(OrderStopLoss() - newStopLoss) > Point)
                  {
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0))
                     {
                        modified++;
                        Print("移动止损到盈亏平衡点成功 - 订单号: ", OrderTicket());
                     }
                  }
               }
            }
         }
      }
   }
   
   return modified > 0;
}

//+------------------------------------------------------------------+
//| 跟踪止损                                                          |
//+------------------------------------------------------------------+
bool CTradingModule::TrailingStop(double trailingPoints = 20.0)
{
   int total = OrdersTotal();
   int modified = 0;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
            {
               double currentPrice = (OrderType() == OP_BUY) ? MarketInfo(m_symbol, MODE_BID) : MarketInfo(m_symbol, MODE_ASK);
               double newStopLoss = 0;
               
               if(OrderType() == OP_BUY)
               {
                  newStopLoss = currentPrice - trailingPoints * Point;
                  if(newStopLoss > OrderStopLoss() || OrderStopLoss() == 0)
                  {
                     newStopLoss = NormalizePrice(newStopLoss);
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0))
                     {
                        modified++;
                     }
                  }
               }
               else if(OrderType() == OP_SELL)
               {
                  newStopLoss = currentPrice + trailingPoints * Point;
                  if(newStopLoss < OrderStopLoss() || OrderStopLoss() == 0)
                  {
                     newStopLoss = NormalizePrice(newStopLoss);
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0))
                     {
                        modified++;
                     }
                  }
               }
            }
         }
      }
   }
   
   return modified > 0;
}

//+------------------------------------------------------------------+
//| 执行手动买单                                                      |
//+------------------------------------------------------------------+
int CTradingModule::ExecuteManualBuyOrder(CGUIModule* guiModule, CPriceModule* priceModule)
{
   if(guiModule == NULL || priceModule == NULL) return -1;
   
   double entryPrice = guiModule.GetEntryPrice();
   double stopLoss = guiModule.GetStopLoss();
   double lotSize = guiModule.GetLotSize();
   
   if(entryPrice <= 0) entryPrice = priceModule.GetAsk();
   
   int ticket = ExecuteBuyOrder(lotSize, stopLoss, 0, "手动买单");
   
   if(ticket > 0)
   {
      Print("手动买单执行成功，订单号: ", ticket);
   }
   
   return ticket;
}

//+------------------------------------------------------------------+
//| 执行手动卖单                                                      |
//+------------------------------------------------------------------+
int CTradingModule::ExecuteManualSellOrder(CGUIModule* guiModule, CPriceModule* priceModule)
{
   if(guiModule == NULL || priceModule == NULL) return -1;
   
   double entryPrice = guiModule.GetEntryPrice();
   double stopLoss = guiModule.GetStopLoss();
   double lotSize = guiModule.GetLotSize();
   
   if(entryPrice <= 0) entryPrice = priceModule.GetBid();
   
   int ticket = ExecuteSellOrder(lotSize, stopLoss, 0, "手动卖单");
   
   if(ticket > 0)
   {
      Print("手动卖单执行成功，订单号: ", ticket);
   }
   
   return ticket;
}

//+------------------------------------------------------------------+
//| 更新手数计算                                                      |
//+------------------------------------------------------------------+
void CTradingModule::UpdateLotSizeCalculation(CGUIModule* guiModule, CPriceModule* priceModule)
{
   if(guiModule == NULL || priceModule == NULL) return;
   
   double entryPrice = guiModule.GetEntryPrice();
   double stopLoss = guiModule.GetStopLoss();
   double riskPercent = guiModule.GetRiskPercent();
   
   if(entryPrice <= 0)
   {
      entryPrice = priceModule.GetAsk(); // 默认使用卖价
   }
   
   if(entryPrice > 0 && stopLoss > 0 && riskPercent > 0)
   {
      double lotSize = CalculateLotSize(entryPrice, stopLoss, riskPercent);
      guiModule.UpdateLotSizeDisplay(lotSize);
   }
}
}

//+------------------------------------------------------------------+
//| 跟踪止损                                                          |
//+------------------------------------------------------------------+
bool CTradingModule::TrailingStop(double trailingPoints = 20.0)
{
   int total = OrdersTotal();
   int modified = 0;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == m_symbol && OrderMagicNumber() == m_magicNumber)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
            {
               double currentPrice = (OrderType() == OP_BUY) ? MarketInfo(m_symbol, MODE_BID) : MarketInfo(m_symbol, MODE_ASK);
               double newStopLoss = 0;
               
               if(OrderType() == OP_BUY)
               {
                  newStopLoss = currentPrice - trailingPoints * Point;
                  if(newStopLoss > OrderStopLoss() || OrderStopLoss() == 0)
                  {
                     newStopLoss = NormalizePrice(newStopLoss);
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0))
                     {
                        modified++;
                     }
                  }
               }
               else if(OrderType() == OP_SELL)
               {
                  newStopLoss = currentPrice + trailingPoints * Point;
                  if(newStopLoss < OrderStopLoss() || OrderStopLoss() == 0)
                  {
                     newStopLoss = NormalizePrice(newStopLoss);
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0))
                     {
                        modified++;
                     }
                  }
               }
            }
         }
      }
   }
   
   return modified > 0;
}

//+------------------------------------------------------------------+
//| 验证交易参数                                                      |
//+------------------------------------------------------------------+
bool CTradingModule::ValidateTradeParams(double lotSize, double stopLoss)
{
   // 检查手数
   double minLot = MarketInfo(m_symbol, MODE_MINLOT);
   double maxLot = MarketInfo(m_symbol, MODE_MAXLOT);
   
   if(lotSize < minLot || lotSize > maxLot)
   {
      Print("手数超出范围: ", lotSize, " (范围: ", minLot, " - ", maxLot, ")");
      return false;
   }
   
   // 检查止损
   if(stopLoss > 0)
   {
      double minStopLevel = MarketInfo(m_symbol, MODE_STOPLEVEL) * Point;
      double currentPrice = MarketInfo(m_symbol, MODE_ASK);
      
      if(MathAbs(currentPrice - stopLoss) < minStopLevel)
      {
         Print("止损距离太近: ", MathAbs(currentPrice - stopLoss) / Point, " 点 (最小: ", minStopLevel / Point, " 点)");
         return false;
      }
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 标准化手数                                                        |
//+------------------------------------------------------------------+
double CTradingModule::NormalizeLotSize(double lotSize)
{
   double minLot = MarketInfo(m_symbol, MODE_MINLOT);
   double maxLot = MarketInfo(m_symbol, MODE_MAXLOT);
   double lotStep = MarketInfo(m_symbol, MODE_LOTSTEP);
   
   lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
   lotSize = MathRound(lotSize / lotStep) * lotStep;
   
   return NormalizeDouble(lotSize, 2);
}

//+------------------------------------------------------------------+
//| 标准化价格                                                        |
//+------------------------------------------------------------------+
double CTradingModule::NormalizePrice(double price)
{
   if(price <= 0) return 0;
   return NormalizeDouble(price, Digits);
}